#ifndef  __QUEUE_HEAD_H__
#define __QUEUE_HEAD_H__
#include <pthread.h>
#include <semaphore.h>

typedef unsigned char   uint8_t;     //无符号8位数

#define MIN(a,b) (a)<(b)?(a):(b)


#define RET_SUCESS 0
#define RET_ERR  -1
#define RET_ERR_NEEDMOREDATA -2


//从 第0开始算，start
#define LEFT_CHAR_BIT_GET_RAW(pData,start,len) ( (u_int8_t)(pData)[0] & ((1<<(8-start)) - (1<<(8-start-len))) )
#define LEFT_CHAR_BIT_GET(pData,start,len) (LEFT_CHAR_BIT_GET_RAW(pData,start,len)>>(8-start-len))

#define RIGHT_CHAR_BIT_GET(pData,start,len) ( ((u_int8_t)(pData)[0]>>(start)) & ((0x01<<(len)) -1) )

#define LITTLE_MAKE_UNINT16(pData) (((u_int8_t)(pData)[0]<<8)  | ((u_int8_t)(pData)[1]))
#define LITTLE_MAKE_UNINT32(pData) (((u_int8_t)(pData)[0]<<24) | ((u_int8_t)(pData)[1]<<16) | ((u_int8_t)(pData)[2]<<8) | (u_int8_t)(pData)[3])

#ifndef DEBUG_LEVE
#define DEBUG_LEVE 3
#endif

#define DEBUG_WARN(fmt, args...) do {printf("WARN![%s,%s,%d]",__FILE__,__FUNCTION__,__LINE__);printf(fmt,##args);} while(0)
#define DEBUG_ERR(fmt, args...) do {printf("ERR!!!![%s,%s,%d]",__FILE__,__FUNCTION__,__LINE__);printf(fmt,##args);} while(0)

#if DEBUG_LEVE >=3
#define DEBUG_INFO1(fmt, args...) do {printf("[%s,%s,%d]",__FILE__,__FUNCTION__,__LINE__);printf(fmt,##args);} while(0)
#define DEBUG_INFO2(fmt, args...) do {printf("[%s,%s,%d]",__FILE__,__FUNCTION__,__LINE__);printf(fmt,##args);} while(0)
#define DEBUG_INFO3(fmt, args...) do {printf("[%s,%s,%d]",__FILE__,__FUNCTION__,__LINE__);printf(fmt,##args);} while(0)
#elif DEBUG_LEVE ==2
#define DEBUG_INFO1(fmt, args...) do {printf("[%s,%s,%d]",__FILE__,__FUNCTION__,__LINE__);printf(fmt,##args);} while(0)
#define DEBUG_INFO2(fmt, args...) do {printf("[%s,%s,%d]",__FILE__,__FUNCTION__,__LINE__);printf(fmt,##args);} while(0)
#define DEBUG_INFO3(fmt, args...)   
#elif DEBUG_LEVE ==1
#define DEBUG_INFO1(fmt, args...) do {printf("[%s,%s,%d]",__FILE__,__FUNCTION__,__LINE__);printf(fmt,##args);} while(0)
#define DEBUG_INFO2(fmt, args...)  
#define DEBUG_INFO3(fmt, args...)  
#endif




typedef struct _QUEUE_NODE_
{
	pthread_mutex_t mlock;
	int datalen;
	uint8_t *data;
} QUEUE_NODE;



class CQueue
{
	public :
		CQueue(int frames,int sigleFrameLen);
		~CQueue();
		
		/*
		* \\no block
		*\\ pram: data, the dest data buffer, len , dest data buffer lenth,
		*\\ return : real  output data lenth
		*/
		int pop(uint8_t *data,int *len);

		
		/*
		*\\ pram: data, the src data, len , the src data lenth
		*\\ return : real  input data lenth
		*/
		int push(uint8_t *data,int len);

		/*	
		* \\ breif :get the data buffer pointer whith block, Manual release is required after use
		*\\  param : **pdata , *plen :the queue data len
		*\\  return -1; no data to get. other the que index will be return ,
		*/
		int getbuffer(uint8_t *pdata,int *plen);
		
		/*
		*\\ breif : get back the que data buffer
		*\\ pram:the que index 
		*\\ return : 0
		*/
		int releasebuffer(int index);

		int addbuffer(uint8_t *data,int len);

		int get_framelen(void){return mframeLen;};
	private:
		void addInindex();
		void addOutindex();
		int IncreaseEffectives();
		int reduceEffectives();
	public:
		int maxFrames;
		int mframeLen;
		QUEUE_NODE *que;
		int mInindex;
		int mOutindex;
		int mEffectives;
		sem_t mSem;

		pthread_mutex_t mIndexlock;
		
	
};
#endif

